//
//  PerfectSessionORM.swift
//  ECApp
//
//  Created by ping Cheng on 2017/10/26.
//

import Foundation
import PerfectSession
import MySQLStORM
import PerfectHTTP
import StORM
/// Holds the session information in memory for duration of request
public class PerfectSessionORM :MySQLStORM {
    /// Token (session id)
    public var token            = ""
    /// Associated UserID. Optional to populate
    public var userid            = ""
    /// Date created, as an Int
    public var created            = 0
    /// Date updated, as an Int
    public var updated            = 0
    /// Idle time set at last update
    public var idle                = SessionConfig.idle
    /// Data held in storage associated with session
    public var data                = [String: Any]()
    
    
    /// IP Address of Session
    public var ipaddress        = ""
    
    /// UserAgent of Session
    public var useragent        = ""
    
    /// Session state
    public var _state            = "recover"
    
    /// Session state
    public var _isOAuth2        = false
    
    /// When creating a new session, the "created" and "updated" properties are set
    public override  init(){
        //self.init()
        super.init()
        created = getNow()
        updated = getNow()
    }
    
    public override func table() -> String {
        return "sessions"
    }
    
    public override func to(_ this: StORMRow) {
        token              = this.data["token"] as! String
        userid       = this.data["userid"] as! String
        created        = this.data["created"] as! Int
        updated           = this.data["updated"] as! Int
        idle              = this.data["idle"] as! Int
        
        fromjson(this.data["data"] as! String)
        
        ipaddress        = this.data["ipaddress"] as! String
        useragent           = this.data["useragent"] as! String
    }
    
    func rows() -> [PerfectSessionORM] {
        var rows = [PerfectSessionORM]()
        for i in 0..<self.results.rows.count {
            let row = PerfectSessionORM()
            row.to(self.results.rows[i])
            rows.append(row)
        }
        return rows
    }
    
    
    /// Makes a JSON Encoded string
    public func tojson() -> String {
        do {
            return try data.jsonEncodedString()
        } catch {
            print(error)
            return "{}"
        }
    }
    
    /// Sets the data property to a [String:Any] from JSON
    public  func fromjson(_ str : String) {
        do {
            data = try str.jsonDecode() as! [String : Any]
        } catch {
            print(error)
        }
    }
    
    /// updates the "updated" property
    public  func touch() {
        updated = getNow()
    }
    
    /// Compares the timestamps and idle to determine if session has expired
    public func isValid(_ request:HTTPRequest) -> Bool {
        if (updated + idle) > getNow() {
            if SessionConfig.IPAddressLock && request.remoteAddress.host != ipaddress {
                return false
            }
            if SessionConfig.userAgentLock && request.header(.userAgent) != useragent {
                return false
            }
            return true
        }
        return false
    }
    
    private func getNow() -> Int {
        return Int(Date().timeIntervalSince1970)
    }
    
    public  func setCSRF(){
        let t = data["csrf"] as? String ?? ""
        if t.isEmpty { data["csrf"] = UUID().uuidString }
    }
}
